//
//  ZODPreviewController+JSHandle.m
//  ZTEOnlineDoc
//
//  Created by 万伟琦 on 2018/9/11.
//  Copyright © 2018年 ZTE. All rights reserved.
//

#import "ZODPreviewController+JSHandle.h"
#import "ZODOnlineReadConst.h"
#import "ZODInternalTools.h"
#import "NSString+ZOD.h"
#import "ZODAESCipher.h"
#import "ZODOnlineDocConfiguration.h"
#import "ZODCacheManager.h"
#import "ZODViewInfo.h"
#import "ZODGlobalStorage.h"
#import "ZODAttInfo.h"
#import "ZODNetworkRequest.h"

#import <objc/runtime.h>


@interface ZODPreviewController ()<WKNavigationDelegate, WKScriptMessageHandler>

@property (nonatomic) ZODViewInfo *viewInfo;

@end

@implementation ZODPreviewController (JSHandle)

- (WKWebViewConfiguration *)webViewJSInteractionDependencyConfiguration {
    WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init];
    
    WKUserContentController *userContentController = [[WKUserContentController alloc] init];
    configuration.userContentController = userContentController;
    
    WKPreferences *preferences = [WKPreferences new];
    preferences.javaScriptCanOpenWindowsAutomatically = YES;
    configuration.preferences = preferences;
    
    [self addJSMessageHandlersToContentController:userContentController];
    
    return configuration;
}

- (void)addJSMessageHandlersToContentController:(WKUserContentController *)cc {
    
    [cc addScriptMessageHandler:self name:@"jsComplete"];
    [cc addScriptMessageHandler:self name:@"cacheImg"];
    [cc addScriptMessageHandler:self name:@"authRetry"];
    [cc addScriptMessageHandler:self name:@"exitView"];

}


#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wobjc-protocol-method-implementation"
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message {
    
    //js传参，调用 OC
    NSString *mName = message.name;
    id mBody = message.body;
    
    if ([mName isEqualToString:@"jsComplete"]) {
        [self jsComplete];
    }
    else if ([mName isEqualToString:@"cacheImg"]) {
        [self cacheImg:mBody];
    }
    else if ([mName isEqualToString:@"authRetry"]) {
        [self authRetry];
    }
    else if ([mName isEqualToString:@"exitView"]) {
        [self exitView];
    }
}
#pragma clang diagnostic pop

#pragma  mark - WKNavigationDelegate

- (void)webView:(WKWebView *)webView didFinishNavigation:(null_unspecified WKNavigation *)navigation{
    
    [self handleJavaScriptAPI];
    
}

- (void)handleJavaScriptAPI {
    
    NSString *docViewUrl = [ZODGlobalStorage sharedStorage].configuration.userBaseUrl;
    NSString *sysCode = self.configuration.sysCode;
    
    
    ZODViewInfo *viewInfo = [ZODInternalTools getViewInfoFromAttInfo:self.attInfo];
    self.viewInfo = viewInfo;
    
    NSString *viJson = [ZODInternalTools JSONStringFromObject:viewInfo];
    NSString *viewInfoEncrypted = [ZODAESCipher zod_encryptAES:viJson key:ZODAES_KEY];
    
    NSString *localCache = [[ZODSharedCacheManager getLocalCachesJSONStringByFileMD5:viewInfo.md5] zod_trim];
    if (!localCache) {
        localCache = @"";
    }
    
    NSString *jsResult = [NSString stringWithFormat:@"view('%@','%@','%@','%@')",docViewUrl, sysCode, viewInfoEncrypted, localCache];
    
    [self.webView evaluateJavaScript:jsResult completionHandler:^(id _Nullable result, NSError * _Nullable error) {
        
    }];
    
//    NSString *authResult = [NSString stringWithFormat:@"authResult('%@')", [NSString stringWithFormat:@"%ld", self.authResult]];
//    [self.webView evaluateJavaScript:authResult completionHandler:^(id _Nullable result, NSError * _Nullable error) {
//        
//    }];
}

- (void)authRequestWithCompletion:(void(^)(ZODAuthResult result))completion {
    
    __weak typeof(self) wself = self;
    [ZODNetworkRequest requestAuthWithAttInfo:self.attInfo success:^{
        wself.authResult = ZODAuthResultPassed;
        dispatch_async(dispatch_get_main_queue(), ^{
            !completion?:completion(wself.authResult);
        });
        
    } failure:^(NSError * _Nonnull error, NSString * _Nonnull errorCode) {
        if (!error) {
            wself.authResult = ZODAuthResultRejected;
        }else {
            wself.authResult = ZODAuthResultTimeout;
        }
        dispatch_async(dispatch_get_main_queue(), ^{
            !completion?:completion(wself.authResult);
        });
    }];
}


#pragma mark - Handle JS Function


- (void)jsComplete {
    // 鉴权结果告诉 JS 侧
    NSString *authResult = [NSString stringWithFormat:@"authResult('%@')", [NSString stringWithFormat:@"%ld", self.authResult]];
    [self.webView evaluateJavaScript:authResult completionHandler:^(id _Nullable result, NSError * _Nullable error) {

    }];
    
//    NSString *showLog = [NSString stringWithFormat:@"showLog('0')"];
//    [self.webView evaluateJavaScript:showLog completionHandler:^(id _Nullable result, NSError * _Nullable error) {
//        NSLog(@"./");
//    }];
}

- (void)cacheImg:(id)body {
    NSDictionary *dict;
    if ([body isKindOfClass:[NSDictionary class]]) {
        dict = (NSDictionary *)body;
    }else {
        return;
    }
    
    NSUInteger totalPages = [(NSNumber *)[dict objectForKey:@"totalPages"] unsignedIntegerValue];
    NSInteger page = [(NSNumber *)[dict objectForKey:@"page"] integerValue];
    NSUInteger base64Len = [(NSNumber *)[dict objectForKey:@"len"] unsignedIntegerValue];
    NSUInteger chunks = [(NSNumber *)[dict objectForKey:@"chunks"] unsignedIntegerValue];
    NSUInteger chunk = [(NSNumber *)[dict objectForKey:@"chunk"] unsignedIntegerValue];
    NSString *chunkString = [dict objectForKey:@"chunkData"];
    
    NSString *docId = self.viewInfo.md5;
    
    
    NSString *auth = [NSString stringWithFormat:@"%ld", self.authResult];
    
//    if ([chunkString containsString:@"YMCAAQMGDBgwYMCAAQMGDBgw"]) {
//        NSLog(@"original chunkString: %@", chunkString);
//    }
    
    [ZODSharedCacheManager cacheImageInMemoryWithDocID:docId authRes:auth totalPages:totalPages currPage:page imgBase64Length:base64Len chunks:chunks currChunk:chunk chunkData:chunkString];
}

- (void)authRetry {
    __weak typeof(self) wself = self;
    [self authRequestWithCompletion:^(ZODAuthResult result) {
        
        NSString *authResult = [NSString stringWithFormat:@"authResult('%@')", [NSString stringWithFormat:@"%ld", result]];
        [wself.webView evaluateJavaScript:authResult completionHandler:^(id _Nullable result, NSError * _Nullable error) {
            
        }];
        
        wself.authResult = result;
        [ZODSharedCacheManager cacheAuthResult:[NSString stringWithFormat:@"%ld", result]];
    }];
}

- (void)exitView {
    [self back];
}


#pragma mark - Property synthesize


static const void *ZODPreviewControllerViewInfoKey = &ZODPreviewControllerViewInfoKey;

- (void)setViewInfo:(ZODViewInfo *)viewInfo {
    objc_setAssociatedObject(self, ZODPreviewControllerViewInfoKey, viewInfo, OBJC_ASSOCIATION_RETAIN);
}

- (ZODViewInfo *)viewInfo {
    return objc_getAssociatedObject(self, ZODPreviewControllerViewInfoKey);
}


@end
